package com.xxx.springboot.util;

import com.google.gson.*;
import com.google.gson.reflect.TypeToken;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.*;

/**
 * Json工具类
 */
public class JsonUtil {

	private static final Logger logger = LoggerFactory.getLogger(JsonUtil.class);

	private final static Gson gson = new GsonBuilder().serializeNulls().create();

    private JsonUtil() {
    }

    /**
     * 将json字符串传入获得相应对象进行操作
     *
     * @param json
     * @param deObj
     * @return
     * @throws Exception
     */
    public static <T> T decodeJson(String json, Class<T> deObj) {
        T obj = null;
        try {
            obj = gson.fromJson(json, deObj);
        } catch (Exception e) {
            logger.error("jsonUtil解析json失败", e);
        }
        return obj;
    }

    /**
     * 将Object转化为json字符串
     *
     * @param obj
     * @return
     * @throws Exception
     */
    public static String encodeJson(Object obj) {
        String json = null;
        try {
            json = gson.toJson(obj);
        } catch (Exception e) {
            logger.error("jsonUtil解析json失败", e);
        }
        return json;
    }

    /**
     * @param json
     * @param clazz
     * @return
     */
    public static <T> List<T> jsonToList(String json, Class<T[]> clazz) {
        T[] array = gson.fromJson(json, clazz);
        return Arrays.asList(array);
    }

    /**
     * @param json
     * @param clazz
     * @return
     */
    public static <T> T[] jsonToArray(String json, Class<T[]> clazz) {
        T[] array = gson.fromJson(json, clazz);
        return array;
    }

    /**
     * @param json
     * @param clazz
     * @return
     */
    public static ArrayList<?> jsonToArrayList(String json, Class<?> clazz) {
        Type type = new TypeToken<ArrayList<JsonObject>>() {
        }.getType();
        ArrayList<JsonObject> jsonObjects = gson.fromJson(json, type);
        ArrayList<Object> arrayList = new ArrayList<Object>();
        for (JsonObject jsonObject : jsonObjects) {
            arrayList.add(gson.fromJson(jsonObject, clazz));
        }
        return arrayList;
    }

    /**
     * 数组转换成map
     *
     * @param vList 需要转换的数组
     * @param kName 实体类中当做主键的属性
     * @return
     */
    public static Map<String, String> listToMap(List<?> vList, String kName) {
        Map<String, String> map = new HashMap<String, String>();
        if (vList == null || kName == null || vList.size() == 0) {
            return map;
        }
        Field kField = getField(vList.get(0).getClass(), kName);
        for (Object Object : vList) {
            try {
                map.put(kField.get(Object).toString(), encodeJson(Object));
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return map;
    }

    private static <V> Field getField(Class<V> clazz, String kName) {
        if (clazz == null || kName == null) {
            return null;
        }
        for (Field fieldElem : clazz.getDeclaredFields()) {
            fieldElem.setAccessible(true);
            if (fieldElem.getName().equals(kName)) {
                return fieldElem;
            }
        }
        return null;
    }

}
